package language;

import compiler.Func;
import static java.util.Collections.EMPTY_MAP;
import java.util.Map;
import java.util.Scanner;
import java.util.function.Function;

public abstract class LFunction<D extends LType, R extends LType> extends LType implements Func {

    public static <D extends LType, R extends LType> LFunction<D, R> of(Function<D, R> function) {
        return new LFunction<D, R>() {
            @Override
            public R accept(LType l, Map<Character, LType> vars) {
                return function.apply((D) l);
            }
        };
    }

    public static LFunction map(LArray first, LArray second) {
        return new LFunction<LType, LType>() {
            @Override
            public LType accept(LType l, Map<Character, LType> vars) {
                return second.get(first.indexOf(l));
            }
        };
    }

    @Override
    public abstract R accept(LType l, Map<Character, LType> vars);

    @Override
    public String toString() {
        return accept(LArray.of(new Scanner(System.in).nextLine()), EMPTY_MAP).toString();
    }
}
